package com.gzhryc.shared_device.oem.code.device;

import com.gzhryc.common.StringTools;
import com.gzhryc.common.json.JsonTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.common.redis.RedisTools;
import com.gzhryc.common.secruity.EncryptTools;
import com.gzhryc.shared_device.cdb.code.ICDBCacheManager;
import com.gzhryc.shared_device.cdb.code.dao.db.BatteryCabinet;
import com.gzhryc.shared_device.cdb.code.dao.db.BatteryCabinetSlot;
import com.gzhryc.shared_device.oem.code.RedisDBConstants;

import org.apache.commons.lang3.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class CDBCacheManager implements ICDBCacheManager {

    static Logger log = Logger.getLogger(CDBCacheManager.class);

    static CDBCacheManager me;

    public static CDBCacheManager self(){
        if(me == null){
            me = new CDBCacheManager();
        }
        return me;
    }

    @Override
    public BatteryCabinet getBatteryCabinet(String deviceSn) {
        if(StringTools.isNotBlank(deviceSn)) {
            String json = RedisTools.get().get(RedisDBConstants.CDB_DEVICE_DB, deviceSn);
            if (JsonTools.isJsonStr(json)) {
                return JsonTools.fromJson(json, BatteryCabinet.class);
            }
        }
        return null;
    }

    @Override
    public void saveBatteryCabinet(BatteryCabinet batteryCabinet) {
        if(batteryCabinet != null && StringTools.isNotBlank(batteryCabinet.getDeviceSn())) {
            RedisTools.get().set(RedisDBConstants.CDB_DEVICE_DB, batteryCabinet.getDeviceSn(), JsonTools.toJson(batteryCabinet));
        }
    }

    @Override
    public void removeBatteryCabinet(String deviceSn) {
        if(StringTools.isNotBlank(deviceSn)) {
            RedisTools.get().delete(RedisDBConstants.CDB_DEVICE_DB,deviceSn);
            //移除所有卡槽信息
            removeBatteryCabinetSlot(deviceSn);
        }
    }

    @Override
    public BatteryCabinetSlot getBatteryCabinetSlot(String deviceSn, Integer slotNum) {
        if(StringTools.isNotBlank(deviceSn) && slotNum != null){
            String key = deviceSn + "_" + slotNum;
            String json = RedisTools.get().get(RedisDBConstants.CDB_DEVICE_SLOT_DB, key);
            if (JsonTools.isJsonStr(json)) {
                return JsonTools.fromJson(json, BatteryCabinetSlot.class);
            }
        }
        return null;
    }

    public List<BatteryCabinetSlot> findBatteryCabinetSlot(String deviceSn) {
        if (StringTools.isNotBlank(deviceSn)) {
            String key = deviceSn + "_*";
            Set<String> keys = RedisTools.get().findKeys(RedisDBConstants.CDB_DEVICE_SLOT_DB, key);
            if (keys != null && keys.size() > 0) {
                List<BatteryCabinetSlot> result = new ArrayList<>();
                for (String cc : keys) {
                    String json = RedisTools.get().get(RedisDBConstants.CDB_DEVICE_SLOT_DB, cc);
                    if (JsonTools.isJsonStr(json)) {
                        result.add(JsonTools.fromJson(json, BatteryCabinetSlot.class));
                    }
                }
                return result;
            }
        }
        return null;
    }

    @Override
    public void saveBatteryCabinetSlot(BatteryCabinetSlot batteryCabinetSlot) {
        if(batteryCabinetSlot != null && StringTools.isNotBlank(batteryCabinetSlot.getDeviceSn()) && batteryCabinetSlot.getSlotNum() != null) {
            String key = batteryCabinetSlot.getDeviceSn() + "_" + batteryCabinetSlot.getSlotNum();
            RedisTools.get().set(RedisDBConstants.CDB_DEVICE_SLOT_DB, key, JsonTools.toJson(batteryCabinetSlot));
        }
    }

    @Override
    public void removeBatteryCabinetSlot(String deviceSn, Integer slotNum) {
        if (StringTools.isNotBlank(deviceSn) && slotNum != null) {
            String key = deviceSn + "_" + slotNum;
            RedisTools.get().delete(RedisDBConstants.CDB_DEVICE_SLOT_DB, key);
        }
    }

    @Override
    public void removeBatteryCabinetSlot(String deviceSn) {
        if(StringTools.isNotBlank(deviceSn)) {
            Jedis jedis = RedisTools.get().getJedis();
            if(jedis != null) {
                try {
                    jedis.select(RedisDBConstants.CDB_DEVICE_SLOT_DB);
                    Set<String> keys = jedis.keys(deviceSn + "_\\d+");
                    if (keys != null && keys.size() > 0) {
                        for (String key : keys) {
                            jedis.del(key);
                        }
                    }
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                } finally {
                    jedis.close();
                }
            }
        }
    }

    public List<BatteryCabinet> findCDBDevice() {
        Jedis jedis = RedisTools.get().getJedis();
        if (jedis != null) {
            try {
                List<BatteryCabinet> deviceList = new ArrayList<>();
                jedis.select(RedisDBConstants.CDB_DEVICE_DB);
                String cursor = ScanParams.SCAN_POINTER_START;
                do {
                    ScanResult<String> result = jedis.scan(cursor);
                    if (result == null)
                        break;
                    cursor = result.getCursor();
                    if (result != null && result.getResult() != null) {
                        for (String key : result.getResult()) {
                            String obj = jedis.get(key);
                            if (StringUtils.isNoneBlank(obj)) {
                                deviceList.add(JsonTools.fromJson(obj, BatteryCabinet.class));
                            }
                        }
                    }
                } while (!cursor.equals(ScanParams.SCAN_POINTER_START));
                return deviceList;
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            } finally {
                jedis.close();
            }
        }
        return null;
    }

    public List<BatteryCabinetSlot> findCDBSlotDevice() {
        Jedis jedis = RedisTools.get().getJedis();
        if (jedis != null) {
            try {
                List<BatteryCabinetSlot> deviceList = new ArrayList<>();
                jedis.select(RedisDBConstants.CDB_DEVICE_SLOT_DB);
                String cursor = ScanParams.SCAN_POINTER_START;
                do {
                    ScanResult<String> result = jedis.scan(cursor);
                    if (result == null)
                        break;
                    cursor = result.getCursor();
                    if (result != null && result.getResult() != null) {
                        for (String key : result.getResult()) {
                            String obj = jedis.get(key);
                            if (StringUtils.isNoneBlank(obj)) {
                                deviceList.add(JsonTools.fromJson(obj, BatteryCabinetSlot.class));
                            }
                        }
                    }
                } while (!cursor.equals(ScanParams.SCAN_POINTER_START));
                return deviceList;
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            } finally {
                jedis.close();
            }
        }
        return null;
    }

    @Override
    public void setCommandResult(String deviceSn, String messageId, String content) {
        if(StringTools.isNotBlank(deviceSn) && StringTools.isNotBlank(messageId) && StringTools.isNotBlank(content)) {
            String key = EncryptTools.md5(deviceSn + "_" + messageId);
            RedisTools.get().set(RedisDBConstants.DEVICE_COMMAND_CACHE_DB, key, content,30L);
        }
    }

    @Override
    public <T> T getCommandResult(String deviceSn,String messageId, Class<T> clazz) {
        if(StringTools.isNotBlank(deviceSn) && StringTools.isNotBlank(messageId) && clazz != null) {
            String key = EncryptTools.md5(deviceSn + "_" + messageId);
            String content = RedisTools.get().get(RedisDBConstants.DEVICE_COMMAND_CACHE_DB, key);
            if (StringTools.isNotBlank(content)) {
                return JsonTools.fromJson(content, clazz);
            }
        }
        return null;
    }
}
